import moment from 'moment';
import _ from 'lodash';
import { TIME_96 } from '@/pages/ETrade/components/helper';
import { DATA_MAP, COLOR_MAP, getTableColumns, getTableData } from '../helper';
import { getCssVariableValue } from '@/utils/utils';

const bgColor = '#161A1D'; // 背景色/整体背景
const borderColor = '#4E5154'; // 分割线/分割线&边框
const fontColor1 = '#D3D4D4'; // 文本颜色/一级文本
const fontColor2 = '#A7A8A9'; // 文本颜色/二级文本
const fontColor3 = '#7A7D7F'; // 文本颜色/三级文本
const fontDisabled = '#646769'; // 文本颜色/不可点击
const fontSize = 14;

const gridCount = [
  { left: '45%', width: '20%', top: 12, bottom: '62%', right: 10 },
  { left: '70%', width: '20%', top: 12, bottom: '62%', right: 10 },
  { left: '45%', width: '20%', bottom: 52, top: '50%', right: 10 },
];
const seriesList = ['实时价格与竞价空间相关性', '日前价格与竞价空间相关性'];
const seriesColor = ['#E86452', '#5E92F6'];
// 特殊处理: 现货价格&竞价空间相关性
const getScatterOption = (d) => {
  let timelineData = [];
  let options = [];
  const removeRepeat = (arr) => {
    const obj = {};
    return arr.filter((item) => {
      const str = item.toString();
      if (!obj[str] && parseFloat(item[0]) && parseFloat(item[1])) {
        obj[str] = true;
        return item;
      }
      return false;
    });
  };

  for (const date in d) {
    let dayAhead, realtime;
    const isAll = date === '全部';
    const tname = isAll ? date : moment(date).format('MMDD');
    timelineData.push(tname);
    const { dayAheadBiddingSpaceCorrelation = [], realtimeBiddingSpaceCorrelation = [] } =
      d[date] || {};
    dayAhead = dayAheadBiddingSpaceCorrelation.map((x, i) => [
      x.xAxis,
      (isAll ? i % 96 : i) + 1,
      x.value,
    ]);
    dayAhead = removeRepeat(dayAhead);
    realtime = realtimeBiddingSpaceCorrelation.map((x, i) => [
      x.xAxis,
      (isAll ? i % 96 : i) + 1,
      x.value,
    ]);
    realtime = removeRepeat(realtime);

    const realtimeXYZ = { xy: [], yz: [], xz: [] };
    const dayAheadXYZ = { xy: [], yz: [], xz: [] };
    realtime.map((t) => {
      realtimeXYZ.xy.push([t[1], t[0]]);
      realtimeXYZ.yz.push([t[1], t[2]]);
      realtimeXYZ.xz.push([t[0], t[2]]);
    });
    dayAhead.map((t) => {
      dayAheadXYZ.xy.push([t[1], t[0]]);
      dayAheadXYZ.yz.push([t[1], t[2]]);
      dayAheadXYZ.xz.push([t[0], t[2]]);
    });
    options.push({
      series: [
        { data: realtime },
        { data: dayAhead },
        { data: removeRepeat(realtimeXYZ.xy) },
        { data: removeRepeat(dayAheadXYZ.xy) },
        { data: removeRepeat(realtimeXYZ.yz) },
        { data: removeRepeat(dayAheadXYZ.yz) },
        { data: removeRepeat(realtimeXYZ.xz) },
        { data: removeRepeat(dayAheadXYZ.xz) },
      ],
    });
  }

  return {
    timeline: {
      axisType: 'category',
      orient: 'vertical',
      autoPlay: false,
      inverse: true,
      playInterval: 3000,
      padding: 0,
      right: 0,
      top: 30,
      bottom: 24,
      width: 48,
      symbol: 'none',
      label: { color: '#A7A8A9' },
      checkpointStyle: {
        symbolSize: 10,
        borderWidth: 2,
        color: getCssVariableValue('--chart-font-color'),
        borderColor: '#18A0FB',
      },
      controlStyle: { itemSize: 13, showNextBtn: false, showPrevBtn: false },
      lineStyle: { show: true, color: borderColor, width: 1, type: 'solid' },
      itemStyle: { color: getCssVariableValue('--chart-font-color') },
      progress: {
        lineStyle: { color: borderColor },
        label: { color: fontColor2, opacity: 0.5 },
      },
      data: timelineData,
      title: '日期选择',
    },
    title: {
      text: '日期选择',
      top: 0,
      right: 0,
      textStyle: { color: fontColor1, fontSize: fontSize, lineHeight: fontSize },
    },
    options,
    diy: true,
    grid3D: {
      width: '45%',
      axisLine: {
        lineStyle: {
          color: getCssVariableValue('--chart-x-line'),
        },
      },
      splitLine: {
        lineStyle: {
          color: getCssVariableValue('--chart-x-line'),
        },
      },
    },
    xAxis3D: {
      name: '竞价空间',
      axisPointer: { lineStyle: { color: getCssVariableValue('--bd-primary') } },
    },
    yAxis3D: {
      name: '时点',
      axisPointer: { lineStyle: { color: getCssVariableValue('--bd-primary') } },
      max: 'dataMax',
    },
    zAxis3D: {
      name: '现货价格',
      axisPointer: { lineStyle: { color: getCssVariableValue('--bd-primary') } },
    },
    grid: [
      ...gridCount.map((t) => ({
        ...t,
        tooltip: {
          show: true,
          confine: true,
          enterable: false,
          trigger: 'axis',
          axisPointer: {
            type: 'line',
            lineStyle: { width: 1, color: borderColor, type: 'solid' },
          },
        },
      })),
    ],
    tooltip: {
      backgroundColor: bgColor,
      borderWidth: 0,
      padding: [fontSize, fontSize],
      textStyle: { fontSize, lineHeight: fontSize, color: fontColor2 },
      position: function (point, params, dom, rect, size) {
        let x = 0,
          y = 0;
        const offset = 0;
        const [pointX, pointY] = point; // 鼠标位置
        const [viewW, viewH] = size.viewSize; // 外层div大小
        const [boxW] = size.contentSize; // 提示框宽度
        // boxW > pointX 说明鼠标左边放不下提示框
        if (pointX > viewW / 2) {
          x = pointX - boxW - offset;
        } else {
          x = pointX + offset;
        }
        if (pointY > viewH / 2) {
          y = viewH / 2;
        }
        return [x, y];
      },
      formatter: (params, ticket, callback) => {
        if (!params.length) {
          const typename = params.seriesIndex ? '日前' : '实时';
          return `<div style="display:flex;align-items:center;">
          <div>
            <div style="display:flex;align-items:center;">
            <div style="width:8px;height:8px;border-radius:4px;background:${params.color};"></div>
            <div style="color:#A7A8A9;margin:0 4px;">${typename}竞价空间</div>
            </div>
            <div style="display:flex;align-items:center;">
              <div style="width:8px;height:8px;border-radius:4px;background:${params.color};"></div>
              <div style="color:#A7A8A9;margin:0 4px;">${typename}时点</div>
            </div>
            <div style="display:flex;align-items:center;">
              <div style="width:8px;height:8px;border-radius:4px;background:${params.color};"></div>
              <div style="color:#A7A8A9;margin:0 4px;">${typename}价格</div>
            </div>
          </div>
          <div style="color:#A7A8A9;text-align:right;width:100%;">
            ${params.value.map((t) => `<div>${t || '-'}</div>`).join('')}
          </div>
        </div>`;
        } else {
          return params
            .map((x) => {
              const typename = x.seriesIndex % 2 ? '日前' : '实时';
              return x.seriesIndex < 6
                ? `<div style="display:flex;align-items:center;">
                    <div>
                      ${x.value
                        .map((t) => {
                          return `<div style="display:flex;align-items:center;">
                                    <div style="width:8px;height:8px;border-radius:4px;background:${
                                      x.color
                                    };"></div>
                                    <div style="color:#A7A8A9;margin:0 4px;">
                                      ${typeof t === 'number' ? '时点' : x.seriesName}
                                    </div>
                                  </div>`;
                        })
                        .join('')}
                    </div>
                    <div style="color:#A7A8A9;text-align:right;width:100%;">
                      ${x.value.map((t) => `<div>${t || '-'}</div>`).join('')}
                    </div>
                  </div>`
                : `<div style="display:flex;align-items:center;">
                    <div>
                      <div style="display:flex;align-items:center;">
                        <div style="width:8px;height:8px;border-radius:4px;background:${
                          x.color
                        };"></div>
                        <div style="color:#A7A8A9;margin:0 4px;">${typename}价格</div>
                      </div>
                      <div style="display:flex;align-items:center;">
                        <div style="width:8px;height:8px;border-radius:4px;background:${
                          x.color
                        };"></div>
                        <div style="color:#A7A8A9;margin:0 4px;">${typename}竞价空间</div>
                      </div>
                    </div>
                    <div style="color:#A7A8A9;text-align:right;width:100%;">
                      <div>${x.value?.[1] || '-'}</div>
                      <div>${x.value?.[0] || '-'}</div>
                    </div>
                  </div>`;
            })
            .join('');
        }
      },
    },
    legend: {
      type: 'scroll',
      width: '100%',
      bottom: 0,
      itemGap: fontSize,
      itemWidth: 16,
      itemHeight: 8,
      textStyle: {
        fontSize,
        lineHeight: fontSize,
        color: getCssVariableValue('--chart-legend-color'),
      },
      padding: 0,
      borderColor: fontDisabled,
      inactiveBorderColor: fontDisabled,
      inactiveBorderWidth: 1,
      inactiveColor: fontDisabled,
    },
    xAxis: [
      ...gridCount.map((t, i) => ({
        type: 'value',
        max: 'dataMax',
        gridIndex: i,
        axisLabel: { rotate: 50, interval: 0, color: getCssVariableValue('--font-40') },
        splitLine: { show: false, color: getCssVariableValue('--chart-x-line') },
      })),
    ],
    yAxis: [
      ...gridCount.map((t, i) => ({ type: 'value', gridIndex: i, splitLine: { show: false } })),
    ],
    dataZoomSlider: true,
    series: [
      ...seriesList.map((t, i) => ({
        type: 'scatter3D',
        symbolSize: 8,
        name: t,
        label: {
          textStyle: {
            color: '#fff',
          },
        },
        itemStyle: {
          color: seriesColor[i],
          borderWidth: 1,
          borderColor: 'rgba(34, 38, 41, 0.5)',
        },
      })),
      ...(() => {
        const item = [];
        gridCount.map((t, i) => {
          seriesList.map((_t, _i) => {
            item.push({
              type: 'scatter',
              name: _t,
              xAxisIndex: i,
              yAxisIndex: i,
              symbolSize: 3,
              legendHoverLink: false,
              itemStyle: {
                color: seriesColor[_i],
                borderWidth: 1,
                borderColor: 'rgba(34, 38, 41, 0.5)',
              },
              emphasis: { itemStyle: { borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.85)' } },
            });
          });
        });
        return item;
      })(),
    ],
  };
};

/**
 * 返回所有图表配置&表格数据
 * @param {*} data 数据 { name: '我是一条线', data: [], key }
 * @param {array} datetimes 点位
 * @param {string} key 数据标识
 * @param {number} isRevised 修正前1、修正后0
 * @param {string} stationName 场站名称
 * @param {array} tableKeys 表格用到的数据键
 * @returns 所有图表配置、表格数据
 */
export const fmtData = ({ dataMap, datetimes, isRevised, stationName, chartKeys, tableKeys }) => {
  let charts = {};
  // 整理图表配置
  chartKeys.map((key) => {
    let dataList = dataMap?.[key] || [];
    if (key === 'biddingSpaceCorrelationMap') {
      // 特殊处理: 现货价格&竞价空间相关性
      charts[key] = getScatterOption(dataList);
    } else {
      if (key === 'spotPrice') {
        // 现货价格
        const _keys = !!isRevised
          ? ['revisedRealtimePrice', 'revisedRecentlyPrice']
          : ['realtimePrice', 'recentlyPrice'];
        dataList = dataList.filter((x) => _keys.includes(x.lineType));
      }
      // 系列
      const series = dataList.map((x) => ({
        ...(COLOR_MAP[x.lineType] || { type: 'line' }),
        name: x.lineName || '',
        data: _.flatten(
          Object.entries(x.pointData)
            .sort((a, b) => (a[0] > b[0] ? 1 : -1))
            .map((y) => y[1].map((z) => z.value)),
        ),
      }));
      charts[key] = {
        series,
        grid: { top: 12, left: 48, bottom: 72, right: 10 },
        tooltip: {},
        legend: {
          textStyle: {
            color: getCssVariableValue('--chart-legend-color'),
          },
        },
        dataZoom: [
          {
            type: 'slider',
            bottom: 26,
            start: 0,
            end: 100,
            height: 20,
            show: true,
            backgroundColor: getCssVariableValue('--bg-form'),
            dataBackground: {
              dataBackground: {
                areaStyle: { opacity: 0 },
                lineStyle: { opacity: 0 },
              },
            },
            selectedDataBackground: {
              areaStyle: {
                color: getCssVariableValue('--font-primary'),
                opacity: 0.15,
              },
              lineStyle: { color: 'transparent' },
            },
            borderColor: 'transparent',
            handleStyle: {
              color: getCssVariableValue('--bg-form'),
              borderColor: getCssVariableValue('--bd'),
            },
            brushSelect: false,
            showDetail: false,
          },
        ],
        xAxis: [
          {
            type: 'category',
            data: datetimes,
            axisLabel: {
              color: getCssVariableValue('--chart-font-color'),
            },
            axisLine: {
              lineStyle: {
                type: 'solid',
                color: getCssVariableValue('--chart-x-line'),
              },
            },
            axisTick: {
              lineStyle: {
                color: getCssVariableValue('--chart-x-line'),
              },
            },
          },
        ],
        yAxis: [
          {
            type: 'value',
            axisLabel: {
              color: getCssVariableValue('--chart-font-color'),
            },
            axisTick: {
              lineStyle: {
                color: getCssVariableValue('--chart-y-line'),
              },
            },
          },
        ],
      };
    }
  });
  // 整理表格数据
  const tableData = getTableData({
    charts,
    stationName,
    tableKeys,
  });
  return {
    charts,
    tableData,
  };
};

const typeOptions = {
  connectingLine: [
    { label: '联络线-总', value: 'total' },
    { label: '联络线-分', value: 'branch' },
  ],
  newEnergy: [
    { label: '新能源-总', value: 'total' },
    { label: '新能源-分', value: 'branch' },
  ],
};

const getConnectingLineData = (data = []) => {
  const obj = [];
  data.forEach((t, i) => {
    Object.entries(t.pointData).forEach((_t, _i) => {
      const length = Object.keys(_t[1]).length;
      Object.entries(_t[1]).forEach((x, xIndex) => {
        if (!_i) {
          obj.push({
            lineName: x[0] + '-' + t.lineName,
            lineType: x[0] + '-' + t.lineName,
            pointData: {},
          });
        }
        obj[xIndex + i * length].pointData[_t[0]] = x[1];
      });
    });
  });
  return obj;
};

export { DATA_MAP, getTableColumns, typeOptions, getConnectingLineData };
